package org.beanstech.util;



import java.sql.Connection;
import java.util.Properties;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class MyHibernateUtil {

	private static SessionFactory sessionFactory;
	static {
		try {
			
			Configuration config = new Configuration().configure();
		   	sessionFactory = config.buildSessionFactory();
			
		} catch (Throwable ex) {
			
			System.err.println("Initial SessionFactory creation failed." + ex);
			throw new ExceptionInInitializerError(ex);
		}
	}
	private static final ThreadLocal<Session> sessionTL = new ThreadLocal<Session>();
	private static MyHibernateUtil hibernateUtil;

	protected MyHibernateUtil() {

	}

	public static MyHibernateUtil getInstance() {
		if (hibernateUtil == null) {
			hibernateUtil = new MyHibernateUtil();
		}
		return hibernateUtil;
	}

	public void shutdown() {
		try {
			sessionFactory.close();
			sessionTL.remove();

		} catch (HibernateException e) {
			e.printStackTrace(System.out);
		}
		sessionFactory = null;
	}
	/**
	      * @param sessionFactory the sessionFactory to set
	      */
	    public void setSessionFactory(SessionFactory sessionFactory) {
	    	MyHibernateUtil.sessionFactory = sessionFactory;
	      }
	    
	    public SessionFactory getSessionFactory() {
	              return sessionFactory;
	          }
	    /**
	    83       * Return the current hibernate session for this thread. If this thread
	    84       * doesn't have one, create a new one.
	    85       */
	          public Session getSessionTL() {
	              try {
	               //  System.out.println("Here");
	            	  getOrCreateSession();
	              } catch (HibernateException he) {
	                  try {
						throw new Exception(he);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
	              }
	              return sessionTL.get();
	      
	          }
	          /**
	          101      * Begin a transaction and store it in a thread-local variable, or return
	           */
	               public Transaction startTransaction() {
	            	 //  System.out.println("START Transaction");
	                   Transaction transaction = getSessionTL().getTransaction();
	                   if (!transaction.isActive()) {
	                       transaction.begin();
	                   }
	                   return transaction;
	               }
	               public void closeSession() {
	            	   		//System.out.println("CLOSE SESSION");
	            	          Session session = sessionTL.get();
	            	            if (session != null && session.isOpen()) {
	            	                session.close();
	            	            }
	            	            sessionTL.set(null);
	            	        }
	            	   
	              public void flushSession() {
	            	            sessionTL.get().flush();
	            	        }
	            	    
	            	    
	            	        public void flushAndCloseSession() {
	            	           Session session = sessionTL.get();
	            	            if (session != null && session.isOpen()) {
	            	                session.flush();
	            	                session.close();
	            	            }
	            	            sessionTL.set(null);
	            	    
	            	        }
	            	    
	            	        public void flushAndClearSession() {
	            	            Session session = getSessionTL();
	            	            if (session.isOpen()) {
	            	               session.flush();
	            	                session.clear();
	            	            }
	            	        }
	            	    
	            	        private Session getOrCreateSession() throws HibernateException {
	            	            if (sessionTL.get() == null) {
	            	                Session session = sessionFactory.openSession();
	            	                sessionTL.set(session);
	            	            }
	            	         return sessionTL.get();
	            	      }
	            	  
	            	      public void commitTransaction() {
	            	          if (getSessionTL().getTransaction().isActive()) {
	            	              getSessionTL().getTransaction().commit();
	            	         }
	            	      }
	            	  
	            	      public void rollbackTransaction() {
	            	          if (getSessionTL().getTransaction().isActive()) {
	            	              getSessionTL().getTransaction().rollback();
	            	          }
	            	       }
	            	   
	            	     
	            	        public MyHibernateUtil getObject() throws Exception {
	            	            return getInstance();
	            	        }
	            	   
	            	       
	            	        public Class<?> getObjectType() {
	            	            return MyHibernateUtil.class;
	            	        }
	            	 
	            	 
	            	      public boolean isSingleton() {
	            	          return true;
	            	      }
	            	  
	            	      public void clearSession() {
	            	          getSessionTL().clear();
	            	      }
	            	  
	            	      public Connection getConnection() {
	            	    	          return getSessionTL().connection();
	            	         }
}
